-- Leviathan (c) v.v.balashoff
local Class = require('leviathan/Class')

local RenderSystem = Class:derive('UIRenderSystem')

function RenderSystem:new(domain)
    self.name = 'RenderSystem'
    self.domain = domain
end

function RenderSystem:draw()
    local domain = self.domain
    if domain.enabled and domain.show and not domain.view then
        local buffer = domain.buffer
        if buffer.canvas then
            local worldX = buffer.worldX
            local worldY = buffer.worldY
            local canvas = buffer.canvas
            love.graphics.setColor(1, 1, 1, buffer.alpha)
            love.graphics.draw(canvas, worldX, worldY)
        end
    end
end

function RenderSystem:update(dt)
    local domain = self.domain
    local buffer = domain.buffer
    -- create canvas if there is none
    if not buffer.canvas then
        buffer.canvas = love.graphics.newCanvas(buffer.w, buffer.h)
    end
    -- rebuild canvas if it is needed
    if domain.changed then
        love.graphics.setCanvas(buffer.canvas)
        love.graphics.clear()
        local comps = domain.components['Renderable']
        for i = 1, #comps do
            local comp = comps[i]
            if comp.entity.enabled and comp.enabled then
                local f = 'draw'..comp.id
                -- TODO переделать на self?
                if RenderSystem[f] then
                    RenderSystem[f](self, comp)
                end
            end
        end
        love.graphics.setCanvas()
        domain.changed = false
    end
end

function RenderSystem:drawBorderComponent(c)
    local entity = c.entity
    local worldX = entity.worldX
    local worldY = entity.worldY
    love.graphics.setColor(c.color, 1)
    for i = 0, c.thickness - 1 do
        love.graphics.rectangle('line', worldX + i, worldY + i, entity.width - (i*2), entity.height - (i*2))
    end
end

function RenderSystem:drawCircleComponent(c)
    local entity = c.entity
    local worldX = entity.worldX + c.x
    local worldY = entity.worldY + c.y
    love.graphics.setColor(c.color, 1)
    love.graphics.circle(c.mode, worldX, worldY, c.r)
end

function RenderSystem:drawRectangleComponent(c)
    local worldX = c.entity.worldX + c.x
    local worldY = c.entity.worldY + c.y
    local alpha = c.entity.alpha
    love.graphics.setColor(c.color[1]/alpha, c.color[2]/alpha, c.color[3]/alpha, alpha)
    love.graphics.rectangle(c.mode, worldX, worldY, c.w, c.h, c.rx, c.ry)
end

function RenderSystem:drawSnowComponent(c)
    love.graphics.setColor(1, 1, 1, 1)
    for _, p in pairs(c.particles) do
        love.graphics.circle('fill', p.x, p.y, p.r, 5)
    end
end

function RenderSystem:drawTextComponent(c)
    local worldX = c.entity.worldX + c.x
    local worldY = c.entity.worldY + c.y
    local alpha = c.entity.alpha
    love.graphics.setFont(c.font)
    -- outline
    if c.outlineColor then
        love.graphics.setColor(c.outlineColor, 1)
        for i = -2, 2 do
            for j = -2, 2 do
                love.graphics.printf(c.text, worldX + i, worldY + j, c.w, c.align)
            end
        end
    end
    -- print text
    love.graphics.setColor(c.color[1]/alpha, c.color[2]/alpha, c.color[3]/alpha, alpha)
    love.graphics.printf(c.text, worldX, worldY, c.w, c.align)
    love.graphics.setColor(1, 1, 1, 1)
end

function RenderSystem:drawTextureComponent(c)
    local worldX = c.entity.worldX + c.x
    local worldY = c.entity.worldY + c.y
    local alpha = c.entity.alpha
    love.graphics.setColor(1, 1, 1, alpha)
    love.graphics.draw(c.buffer, worldX, worldY)
end

function RenderSystem:drawViewerComponent(c)
    if not c.buffer then
        return
    end
    local worldX = c.entity.worldX + c.x
    local worldY = c.entity.worldY + c.y
    local alpha = c.entity.alpha
    love.graphics.setColor(1, 1, 1, alpha)
    love.graphics.draw(c.buffer, worldX, worldY)
end

return RenderSystem
